Skip to content

fix: use fish long options for multi-character flag names - #2453

Merged
Juneezee merged 1 commit into
urfave:mainfrom
SulimanAbdulrazzaq:fix/fish-short-long-option-names
Oct 7, 2026
Merged

Juneezee merged 1 commit into
urfave:mainfrom
SulimanAbdulrazzaq:fix/fish-short-long-option-names

Conversation

@SulimanAbdulrazzaq

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • bug

What this PR does / why we need it:

ToFishCompletion writes the first name of a flag as -l and every other name as -s. fish reads the argument of complete -s as a group of one-character options, so an alias with more than one character is registered as several unrelated short options instead of one long option, and a one-character first name is registered as a long option.

For Name: "verbose", Aliases: []string{"loud", "v"} the generated line was -l verbose -s loud -s v. With fish 3.7.0 on the old output, complete -C 'greet --lo' returns nothing and complete -C 'greet -l' offers -ld -lo -lp -lt -lu -lv. For Name: "o", Aliases: []string{"output", "out"} the old output registered --o and the short options o, u, t, p.

The generator now uses -s for a one-character name and -l for any other name, whichever position it has in the flag's names. With the change, complete -C 'greet --lo' returns --loud and complete -C 'greet --ou' returns --out and --output.

  • fish.go: choose -s or -l per name.
  • testdata/expected-fish-full.fish: the fl and sub-fl aliases are now -l fl and -l sub-fl.
  • fish_test.go: new TestFishCompletionShortAndLongNames.

Which issue(s) this PR fixes:

NONE

Special notes for your reviewer:

Not changed on purpose: command aliases are still not offered by the fish completion, and the bash, zsh and PowerShell scripts do not use these options. Flags whose names are all one character, or whose aliases are all one character (the existing help golden file), generate the same output as before.

Testing

make lint, make vet, make test, make test GFLAGS='--tags urfave_cli_no_template', make generate, make diffcheck and make v3diff pass in a fork run on ubuntu. The new test fails without the change and passes with it. A fork step also sources the generated script in fish 3.7.0 and runs complete -C as described above.

Release Notes

Fish completion: flag names longer than one character are now generated as long options (`-l`), and one-character names as short options (`-s`), wherever they appear in a flag's names.

fish reads the argument of complete -s as a group of one-character options. The fish completion generator wrote every name after the first as -s and the first name as -l, so an alias such as fl became the options f and l instead of --fl, and a one-character name was registered as --o. Write a name as -s only when it is a single character and as -l otherwise.
@SulimanAbdulrazzaq
SulimanAbdulrazzaq requested a review from a team as a code owner October 3, 2026 10:38
@greptile-apps

greptile-apps Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Fixes fish shell completion flag formatting logic.

The PR appears safe to merge.

Summary

The PR selects fish short or long completion options by each flag name’s length rather than its position, adds a regression test, and updates the expected completion script. No actionable issues were identified.

Reviews (1) · Last reviewed commit: "fix: use fish long options for multi-cha..."

@Juneezee Juneezee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

I also checked it with fish 4.9.3, using the flags from the new test:

complete -C 'greet --lo'   # main: (nothing)                   PR: --loud
complete -C 'greet -l'     # main: -ld -lo -lp -lt -lu -lv     PR: --loud
complete -C 'greet --ou'   # main: (nothing)                   PR: --out --output

prefixFor uses the same one-character rule for help output, so completion now matches what help prints (--verbose, --loud, -v and -o string, --output string, --out string):

cli/docs.go

Lines 11 to 19 in 2f64589

func prefixFor(name string) (prefix string) {
if utf8.RuneCountInString(name) == 1 {
prefix = "-"
} else {
prefix = "--"
}
return prefix
}

A small note on the description, no change to the code needed: "Flags whose names are all one character ... generate the same output as before" is not quite right. A flag with only Name: "x" changes from -l x to -s x. That is the intended fix (the same as the o case), and the release note already covers it.

@Juneezee
Juneezee merged commit bb59353 into urfave:main Oct 7, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants